home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 5 / BBS in a Box -Volume V (BBS in a Box) (April 1992).iso / Files / Apple / Apple II TNs(Text).cpt / Apple II TNs(Text) / IIGS / TN.IIGS.004 / TN.IIGS.004
Encoding:
Text File  |  1989-11-15  |  12.0 KB  |  259 lines  |  [TEXT/pdos]

  1. Apple II
  2. Technical Notes
  3. _____________________________________________________________________________
  4.                                                   Developer Technical Support
  5.  
  6.  
  7. Apple IIGS
  8. #4:    Changing Graphics Modes in Mid-Application
  9.  
  10. Revised by:    Dan Oliver                                       November 1988
  11. Written by:    Dan Oliver                                        October 1986
  12.  
  13. This Technical Note discusses how to switch between the two graphics modes, 
  14. 320 and 640 horizontal resolution, while running an application which uses the 
  15. Window, Control, and Menu Managers.
  16. _____________________________________________________________________________
  17.  
  18.  
  19. Why Change Resolution?
  20.  
  21. Why not?  There are certain applications where the ability to run in both 
  22. modes is essential; most graphics applications fall into this catagory.  Other 
  23. applications might switch modes to provide features which their competitors 
  24. lack; a financial application might display figures in 640 mode and charts in 
  25. 320 mode.  Still other applications may want to give the user the choice.  A 
  26. word processor might seem useful only in 640 mode, but what if the user wants 
  27. to print greeting cards with pictures?  The user does not need the line length 
  28. provided in 640 mode but does need the added color of 320 mode for the 
  29. pictures.
  30.  
  31. Let me preach a little.  I have worked on other machines with different 
  32. graphic modes and learned some things that might be of use to application 
  33. programmers.  Many application programmers fight mode switching with either 
  34. rhetoric or apathy, then when users expect their software to run in either 
  35. mode, they become frustrated when it does not allow switching.  To avoid the 
  36. problem of frustrating the user, you can provide mode switching (which is not 
  37. as hard as you might think).
  38.  
  39.  
  40. How To Change Modes
  41.  
  42. First, I will assume we are in an application which is running with a system 
  43. menu bar, a few visible windows with scroll bars, and one window with some 
  44. standard controls.  At some point, the user decides to change modes, possibly 
  45. via a menu item thoughtfully provided by the application programmer.  Your 
  46. change mode handler might look like the following:
  47.  
  48. ;
  49. ; --- This step is necessary if QuickDraw Auxiliary is started -----------------------------
  50.               _QDAuxShutDown          ;Shut down QDAux first
  51. ; ------------------------------------------------------------------------------------------
  52.               _QDShutdown             ;Shut down QuickDraw.
  53.                                       ;This will turn graphics off so you will see
  54.                                       ;the text screen for a second (a advertisement
  55.                                       ;might go here).
  56. ;
  57.               lda    <mode            ;Variable that holds current resolution.
  58.               eor    #$0080           ;Flip the mode bit, $0000 = 320, $0080 = 640.
  59.               sta    <mode            ;New value will be used to start the new mode.
  60. ;
  61.               pei    <QDzpage         ;Pass the direct pages allocated for QuickDraw.
  62.               pei    <mode            ;New mode.
  63.               pei    <QDwidth         ;0 for screen width; other numbers for printing
  64.               pei    <MyID            ;Pass my ID number.
  65.               _QDStartup              ;Restart QuickDraw in the new mode.
  66. ;
  67.               _GrafOff                ;Turn screen off because changing mode
  68.                                       ;may not be pretty.
  69. ; --- This step is necessary if you need QuickDraw Auxiliary  ------------------------------
  70.               _QDAuxStartUp           ;Start QDAux again
  71. ; ------------------------------------------------------------------------------------------
  72. ;
  73. ;
  74. ; --- Fix up the cursor for the new mode ---------------------------------------------------
  75. ;
  76.               pea    0                ;Pass minimum cursor X position.
  77.               lda    #319             ;Maximum X position for 320 mode.
  78.               ldx    <mode            ;320 or 640 mode?
  79.               beq    store
  80.               lda    #639             ;Maximum X position for 640 mode.
  81. store         pha                     ;Pass maximum cursor X position.
  82.               pea    0                ;Pass minimum Y cursor position.
  83.               pea    199              ;Pass maximum Y cursor position.
  84.               _ClampMouse             ;Clamp the cursor to the new screen size.
  85. ;
  86.               _HomeMouse              ;Move the cursor to 0,0 to make sure
  87.                                       ;it is on screen.
  88.               _ShowCursor             ;Make cursor visible.
  89. ;
  90. ;
  91. ; --- Tell tools about the change ----------------------------------------------------------
  92. ;
  93.               _WindNewRes             ;Tell Window Manager about the change.
  94.               _MenuNewRes             ;Tell Menu Manager about the change.
  95.               _CtlNewRes              ;Tell Control Manager about the change.
  96. ;
  97. ;
  98. ; --- Fix the screen to look good ----------------------------------------------------------
  99. ;
  100. ;    Here you might want to change the color of the desktop, windows, menus or
  101. ;    controls to look good for the new mode.
  102. ;
  103. ;    See example below.
  104. ;
  105. ; --- Redraw the screen in the new mode ----------------------------------------------------
  106. ;
  107.               pea    0                Pass flag to draw entire screen.
  108.               pea    0
  109.               _RefreshDesktop         Draw entire screen.
  110. ;
  111.               _GrafOn                 Now show the new screen.
  112. ;
  113.  
  114. That is not too bad, but I left out the fun part.  Before the RefreshDesktop 
  115. there is a section named "Fix up the screen to look good."  This section is 
  116. where you might want to put some color into windows, controls, and menus if 
  117. you are switching to 320 mode; changing colors is not required, but there are 
  118. some things which are.
  119.  
  120. When switching from 640 mode to 320 mode, some windows (both visible and 
  121. invisible) might be positioned off the screen in 320 mode.  The first way to 
  122. handle this problem is easy for you, the programmer, but not so great for the 
  123. user:  close all the windows before changing modes, then position them 
  124. correctly when the user opens them in the new mode.  The second way to handle 
  125. the problem is to walk the window list and move all the windows, maybe even 
  126. change their sizes.  You could double each window's horizontal starting 
  127. position and width when switching from 320 mode to 640 mode and halve it when 
  128. changing from 640 mode to 320 mode.  The vertical position and height will be 
  129. okay.  An example of the second method is given below.
  130.  
  131. Windows with vertical scroll bars in the window frame are the same width when 
  132. you change modes, so switching from 320 mode to 640 mode results in a narrower 
  133. bar while changing from 640 mode to 320 mode produces a wider bar.  The bars 
  134. change to the correct size as soon as the user resizes the window since 
  135. SizeWindow deletes the old scroll bars and allocates new ones according to the 
  136. current mode.  If, as suggested above, you resize all the windows after the 
  137. mode change and before calling RefreshDesktop, you should be in good shape.  
  138. If you choose not the follow this recommendation, you should call SizeWindow 
  139. for every window with scroll bars and change the size of each window at least 
  140. one pixel since SizeWindow will not do anything if the passed size is not 
  141. different  than the current size.
  142.  
  143. You should dispose of scroll bars in a window's content region and recreate 
  144. them; this is not nice, but very few applications have scroll bars in a 
  145. window's content region.
  146.  
  147. WindNewRes resets the desktop shape and pattern and the Window Manager's icon 
  148. font to their defaults for the new mode, so if you changed any of these, you 
  149. must add to or subtract from the desktop again and reinitialize to your custom 
  150. pattern or icon font again.
  151.  
  152. CtlNewRes resets the Control Manager's icon font to the default for the new 
  153. mode, so if you changed the Control Manager's icon font, you must reinitialize 
  154. to your icon font again.
  155.  
  156.  
  157. Repositioning and Resizing Windows in the New Mode
  158.  
  159. Here is an example of how to reposition and resize windows in the new mode.
  160.  
  161. ;    QuickDraw and the tools have already been reinitialized in the new mode.
  162. ;
  163. ;    mode = $0000 if in 320 mode, $0080 if in 640 mode.
  164. ;
  165. BoundsRect    equ    8                ;Offsets in port record from QuickDraw document.
  166. PortRect      equ    16
  167. ;
  168. ;
  169.               pha                     ;Space for result.
  170.               pha
  171.               _FrontWindow            ;Start with the top most window, this assumes
  172.               bra    enter            ;there are no invisible windows ahead of the
  173.                                       ;active window in the window list.
  174. ;
  175. ;
  176. loop          ldy    #BoundsRect+2
  177.               lda    [window],y       ;Get window's starting horizontal position.
  178.               eor    #$FFFF           ;Convert to screen coordinate (negate it).
  179.               inc    a
  180.               asl    a                ;Double it if we're going to 640 mode.
  181.               ldx    <mode            ;Going to 320 or 640 mode?
  182.               bne    store1           ;Ready if we're going to 640.
  183.               lsr    a                ;Otherwise, undo the doubling,
  184.               lsr    a                ;and halve the starting horizontal position.
  185. store1        pha                     ;Pass window's new X starting position.
  186.               ldy    #BoundsRect    
  187.               lda    [window],y       ;Get window's starting vertical position.
  188.               eor    #$FFFF           ;Convert to screen coordinate.
  189.               inc    a
  190.               pha                     ;Pass window's current Y starting position.
  191.               pei    <window+2        ;Pass window to move.
  192.               pei    <window
  193.               _MoveWindow             ;Move the window to its new position.
  194. ;
  195.               ldy    #PortRect+6      ;Get window's current width.
  196.               lda    [window],y       ;(This assumes the window's origin is 0,0.)
  197.               asl    a                ;Double the window's width if going to 640 mode.
  198.               ldx    <mode            ;Going to 320 or 640 mode?
  199.               bne    store2           ;Ready if we're going to 640.
  200.               lsr    a                ;Otherwise, undo the doubling,
  201.               lsr    a                ;and halve the window's width.
  202. store2        pha                     ;Pass window's new width.
  203.               ldy    #PortRect+4
  204.               lda    [window],y       ;Get window's height.
  205.               pha                     ;Pass window's current height.
  206.               pei    <window+2        ;Pass window to resize.
  207.               pei    <window
  208.               _SizeWindow             ;Resize the window.
  209. ;
  210.               pha                     ;Space for result.
  211.               pha
  212.               pei    <window+2        ;Pass pointer to window we just processed.
  213.               pei    <window
  214.               _GetNextWindow          ;Get the pointer to the next window.
  215. ;
  216. enter         pla                     ;Remember the pointer to this window.
  217.               sta    <window
  218.               pla
  219.               sta    <window+2
  220. ;
  221.               ora    <window          ;Are there any more windows?
  222.               bne    loop
  223. ;
  224.  
  225. WindNewRes
  226.  
  227. Generally, WindNewRes does the following:
  228.  
  229. o    closes its port
  230. o    opens its port again, now in the new mode
  231. o    reinitializes the desktop size
  232. o    chooses the proper icon font for close and zoom boxes
  233. o    reinitializes the desktop pattern
  234. o    changes the SCB byte of each window's port to the new mode
  235. o    recomputes the VisRgn for each window
  236.  
  237. MenuNewRes
  238.  
  239. Generally, MenuNewRes does the following:
  240.  
  241. o    closes its port
  242. o    opens its port again, now in the new mode
  243. o    reinitializes internal parameters, like vertical line width, for the new 
  244.      mode
  245. o    reinitializes the color palette via InitPalette
  246. o    subtracts the system menu bar from the desktop (this is why you must call 
  247.      WindNewRes first)
  248. o    draws the system menu bar
  249.  
  250. CtlNewRes
  251.  
  252. Generally, CtlNewRes does the following:
  253.  
  254. o    chooses the proper icon font for radio button, check box, grow box and 
  255.      scroll bar arrows
  256. o    reinitializes internal parameters, like vertical line width, for the new 
  257.      mode
  258.  
  259.